#include "myarray.h"

#include <stdexcept>
#include <QString>

namespace sk {

MyArray::MyArray() {
    arr = new int[DEFAULT_ARR_SIZE];
    arrSize = DEFAULT_ARR_SIZE;
    size = 0;
    bIsOwnsMemory = TRUE;
}

MyArray::~MyArray() {
    if (bIsOwnsMemory && arr != NULL) delete[] arr;
}

void MyArray::add(int val) {
    if (size == arrSize) {
        int* tmp = new int[size * 2];
        arrSize = size * 2;
        memcpy(tmp, arr, size * sizeof(int));
        delete[] arr;
        arr = tmp;
    }
    arr[size++] = val;
}

int MyArray::get(int index) const {
    if (index < 0 || index >= size)
        throw std::invalid_argument(QString().sprintf("Index is out of range: %d", index).toStdString());

    return arr[index];
}

int MyArray::takeLast() {
    if (size < 1)
        throw std::invalid_argument(QString().sprintf("Can't take last element, array is empty").toStdString());

    int result = arr[size--];

    if (size <= arrSize / 4 && arrSize / 2 > DEFAULT_ARR_SIZE) {
        int* tmp = new int[arrSize / 2];
        arrSize = arrSize / 2;
        memcpy(tmp, arr, size * sizeof(int));
        delete[] arr;
        arr = tmp;
    }

    return result;
}

void MyArray::print() {
    for (int i = 0; i < size; i++) {
        printf("%d", arr[i]);
    }
}

void mySwap(MyArray* arr, int x, int y) {
    std::swap(arr->arr[x], arr->arr[y]);
}

MyArray& MyArray::operator=(const MyArray& arr) {
    this->arr = arr.arr;
    this->arrSize = arr.arrSize;
    this->size = arr.size;
    this->bIsOwnsMemory = TRUE;
    return *this;
}

MyArray::MyArray(const MyArray& arr) {
    this->arr = arr.arr;
    this->arrSize = arr.arrSize;
    this->size = arr.size;
    this->bIsOwnsMemory = TRUE;
}

MyArray::MyArray(int *arr, int length) {
    this->arr = arr;
    this->arrSize = length;
    this->size = length;
    this->bIsOwnsMemory = FALSE;
}

}
